package com.chiancloud.shield.core.registry.info;

import com.chiancloud.shield.core.exception.ShieldException;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import java.net.*;

/**
 * Created by wanghui on 14-8-20.
 */
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class RegisteredEndpoint {

    public static final String TYPE_URL = "url";
    public static final String TYPE_HOSTNAME = "hostname";
    public static final String TYPE_INETADDRESS = "inetaddress";
    public static final String TYPE_PATH = "path";
    public static final String PROTOCOL_TCP = "tcp";
    public static final String PROTOCOL_UDP = "udp";
    public static final String PROTOCOL_HTTP = "http";
    public static final String PROTOCOL_HTTPS = "http";
    public static final String PROTOCOL_HADOOP_RPC = "org.apache.hadoop.ipc.RPC";
    public static final String PROTOCOL_HADOOP_PROTOBUF = "org.apache.hadoop.ipc.Protobuf";
    public String address;
    public String protocol = "";
    public String type = "";
    public String description = "";
    public RegisteredEndpoint() {
    }

    public RegisteredEndpoint(String address,
                              String protocol,
                              String type,
                              String description) {
        this.address = address;
        this.protocol = protocol;
        this.type = type;
        this.description = description;
    }

    public RegisteredEndpoint(URI uri,
                              String description) {

        this.address = uri.toString();
        this.protocol = uri.getScheme();
        this.type = TYPE_URL;
        this.description = description;
    }
    public RegisteredEndpoint(InetSocketAddress address,
                              String protocol,
                              String description) {

        this.address = address.toString();
        this.protocol = protocol;
        this.type = TYPE_INETADDRESS;
        this.description = description;
    }

    public RegisteredEndpoint(URL url,
                              String description) throws URISyntaxException {
        this(url.toURI(), description);
    }

    public URL asURL() throws ShieldException {
        verifyEndpointType(TYPE_URL);
        try {
            return new URL(address);
        } catch (MalformedURLException e) {
            throw new ShieldException(-1, e,
                    "could not create a URL from %s : %s", address, e.toString());
        }
    }

    @Override
    public String toString() {
        final StringBuilder sb =
                new StringBuilder();
        if (TYPE_URL.equals(type)) {
            sb.append(address);
        } else {
            sb.append("protocol='").append(protocol).append('\'');
            sb.append(" address='").append(address).append('\'');
            sb.append(" type='").append(type).append('\'');
        }
        sb.append(" -- \"").append(description).append('"');
        return sb.toString();
    }


    public void verifyEndpointType(String desiredType) throws ShieldException {
        if (!type.equals(desiredType)) {
            throw new ShieldException(-1, "Body of endpoint is of type %s and not %s",
                    type, desiredType);
        }
    }
}
